package org.joy;

import org.apache.shiro.codec.Hex;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;

public class SignedURL {
    static String accessid = "1af1555a15c952166a8cb899179bd74f93c17776";
    static String secretKey = "2kNPUz7QpNAC2CyTlB9EK4qS7986jyCKdK+o0Zyv8co=";
    static  Calendar calendar = Calendar.getInstance(Locale.ROOT);

    public static void main(String[] args) throws NoSuchAlgorithmException, UnsupportedEncodingException, InvalidKeyException {
        Date nowTime = calendar.getTime();
        String x_amz_date = new SimpleDateFormat ("yyyyMMdd'T'hhmmss'Z'").format(nowTime.getTime());
        String date = x_amz_date.split("T")[0];
        String ns ="cnjxmruwj0jf";

        String region_name = "sa-saopaulo-1";
        String service_name = "s3";
        String x_amz_credential=accessid+"/"+date+"/"+region_name+"/"+service_name+"/aws4_request";
        String x_amz_algorithm = "AWS4-HMAC-SHA256";
        String x_amz_expires ="86400";
        String x_amz_signedHeaders="host";
        String httpMethod= "PUT";
        String objectname_url="/testoss/bigdemo";
        String host= ns+".compat.objectstorage."+region_name+".oraclecloud.com";
        String payload ="UNSIGNED-PAYLOAD";
        MessageDigest digest = MessageDigest.getInstance("SHA-256");

        String params =      URLEncoder.encode("X-Amz-Algorithm")+"="+ URLEncoder.encode(x_amz_algorithm)+"&"
                + URLEncoder.encode("X-Amz-Credential")+"="+ URLEncoder.encode(x_amz_credential)+"&"
                + URLEncoder.encode("X-Amz-Date")+"="+ URLEncoder.encode(x_amz_date)+"&"
                + URLEncoder.encode("X-Amz-Expires")+"="+ URLEncoder.encode(x_amz_expires)+"&"
                + URLEncoder.encode("X-Amz-SignedHeaders")+"="+ URLEncoder.encode(x_amz_signedHeaders);

        String request=httpMethod+"\n"
                + objectname_url+"\n"
                + params+ "\n"
                + x_amz_signedHeaders.toLowerCase()+":"+host.trim()+"\n"
                + "\n"
                + x_amz_signedHeaders.toLowerCase() +"\n"
                + payload;

        byte[] encodedhash = digest.digest(request.getBytes(StandardCharsets.UTF_8));

        String hashrequest= Hex.encodeToString(encodedhash);

        String strtosign = x_amz_algorithm +"\n"
                + x_amz_date +"\n"
                + date+"/"+region_name+"/"+service_name+"/aws4_request"+"\n"
                + hashrequest;
        System.out.println(strtosign);
        String signature = Hex.encodeToString(hmacSHA256(getSignatureKey(secretKey,date,region_name,service_name),strtosign));

        String url ="https://"+host+objectname_url+"?"+params+"&X-Amz-Signature="+signature;
        System.out.println(url);
        System.out.println(Base64.getEncoder().encodeToString(url.getBytes()));
    }


    private static byte[] getSignatureKey(String key, String date, String regionName, String serviceName)
            throws UnsupportedEncodingException, InvalidKeyException, NoSuchAlgorithmException {
        byte[] kSecret = ("AWS4" + key).getBytes("UTF-8");
        byte[] kDate = hmacSHA256(kSecret, date);
        byte[] kRegion = hmacSHA256(kDate, regionName);
        byte[] kService = hmacSHA256(kRegion, serviceName);
        return hmacSHA256(kService, "aws4_request");
    }

    private static byte[] hmacSHA256(byte[] key, String data) throws UnsupportedEncodingException, InvalidKeyException,
            NoSuchAlgorithmException {

        String algorithm = "HmacSHA256";
        Mac mac = Mac.getInstance(algorithm);
        mac.init(new SecretKeySpec(key, algorithm));
        return mac.doFinal(data.getBytes());
    }
}
